package com.tools.common.container;

import com.tools.common.object.Force;
import com.tools.common.object.Note;
import com.tools.common.object.string.StrKit;

import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 集合、数组容器
 * 操作的工具类
 * */
@SuppressWarnings("unchecked")
@Note("集合、数组容器操作的工具类")
public final class RowKit extends RowBasicKit {

    private RowKit() {}

    /* *******************************************************************************************
     *
     *           List 集合
     *
     * *******************************************************************************************
     * */

    @SafeVarargs
    public static <T>ArrayList<T> toArrayList(T... elements) {
        return toArrayList((Force<T>) null, elements);
    }

    public static <T>ArrayList<T> toArrayList(Force<T> force, T... elements) {
        if(elements == null) return new ArrayList<>();
        int length = elements.length;
        if(length == 0) return new ArrayList<>();
        return (ArrayList<T>) private_asCollection(new ArrayList<>(length), elements, force);
    }

    public static <T>ArrayList<T> toArrayList(Comparator<? super T> c, T... elements) {
        return toArrayList(c, null, elements);
    }

    public static <T>ArrayList<T> toArrayList(Comparator<? super T> c, Force<T> force, T... elements) {
        ArrayList<T> result = toArrayList(force, elements);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>ArrayList<T> toArrayList(Collection<? extends T> elements) {
        return toArrayList(elements, (Force<T>) null);
    }

    public static <T>ArrayList<T> toArrayList(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new ArrayList<>();
        if(force == null) return new ArrayList<>(elements);
        return (ArrayList<T>) private_asCollection(new ArrayList<>(elements.size()), elements, force);
    }

    public static <T>ArrayList<T> toArrayList(Collection<? extends T> elements, Comparator<? super T> c) {
        return toArrayList(elements, (Force<T>) null, c);
    }

    public static <T>ArrayList<T> toArrayList(Collection<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        ArrayList<T> result = toArrayList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>ArrayList<T> toArrayList(OwnRows<? extends T> elements) {
        return toArrayList(elements, (Force<T>) null);
    }

    public static <T>ArrayList<T> toArrayList(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new ArrayList<>();
        return (ArrayList<T>) private_asCollection(new ArrayList<>(elements.size()), elements, force);
    }

    public static <T>ArrayList<T> toArrayList(OwnRows<? extends T> elements, Comparator<? super T> c) {
        return toArrayList(elements, (Force<T>) null, c);
    }

    public static <T>ArrayList<T> toArrayList(OwnRows<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        ArrayList<T> result = toArrayList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>ArrayList<T> toArrayList(Iterable<? extends T> elements) {
        return toArrayList(elements, (Force<T>) null);
    }

    public static <T>ArrayList<T> toArrayList(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new ArrayList<>();
        int size = default_getIterableLength(elements);
        if(size == 0) return new ArrayList<>();
        return (ArrayList<T>) private_asCollection(new ArrayList<>(size), elements, force);
    }

    public static <T>ArrayList<T> toArrayList(Iterable<? extends T> elements, Comparator<? super T> c) {
        return toArrayList(elements, (Force<T>) null, c);
    }

    public static <T>ArrayList<T> toArrayList(Iterable<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        ArrayList<T> result = toArrayList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }


    @SafeVarargs
    public static <T>LinkedList<T> toLinkedList(T... elements) {
        return toLinkedList((Force<T>) null, elements);
    }

    public static <T>LinkedList<T> toLinkedList(Force<T> force, T... elements) {
        if(elements == null || elements.length == 0) return new LinkedList<>();
        return (LinkedList<T>) private_asCollection(new LinkedList<>(), elements, force);
    }

    public static <T>LinkedList<T> toLinkedList(Comparator<? super T> c, T... elements) {
        return toLinkedList(c, null, elements);
    }

    public static <T>LinkedList<T> toLinkedList(Comparator<? super T> c, Force<T> force, T... elements) {
        LinkedList<T> result = toLinkedList(force, elements);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>LinkedList<T> toLinkedList(Collection<? extends T> elements) {
        return toLinkedList(elements, (Force<T>) null);
    }

    public static <T>LinkedList<T> toLinkedList(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new LinkedList<>();
        if(force == null) return new LinkedList<>(elements);
        return (LinkedList<T>) private_asCollection(new LinkedList<>(), elements, force);
    }

    public static <T>LinkedList<T> toLinkedList(Collection<? extends T> elements, Comparator<? super T> c) {
        return toLinkedList(elements, (Force<T>) null, c);
    }

    public static <T>LinkedList<T> toLinkedList(Collection<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        LinkedList<T> result = toLinkedList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>LinkedList<T> toLinkedList(OwnRows<? extends T> elements) {
        return toLinkedList(elements, (Force<T>) null);
    }

    public static <T>LinkedList<T> toLinkedList(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new LinkedList<>();
        return (LinkedList<T>) private_asCollection(new LinkedList<>(), elements, force);
    }

    public static <T>LinkedList<T> toLinkedList(OwnRows<? extends T> elements, Comparator<? super T> c) {
        return toLinkedList(elements, (Force<T>) null, c);
    }

    public static <T>LinkedList<T> toLinkedList(OwnRows<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        LinkedList<T> result = toLinkedList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>LinkedList<T> toLinkedList(Iterable<? extends T> elements) {
        return toLinkedList(elements, (Force<T>) null);
    }

    public static <T>LinkedList<T> toLinkedList(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new LinkedList<>();
        return (LinkedList<T>) private_asCollection(new LinkedList<>(), elements, force);
    }

    public static <T>LinkedList<T> toLinkedList(Iterable<? extends T> elements, Comparator<? super T> c) {
        return toLinkedList(elements, (Force<T>) null, c);
    }

    public static <T>LinkedList<T> toLinkedList(Iterable<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        LinkedList<T> result = toLinkedList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    @SafeVarargs
    public static <T> CopyOnWriteArrayList<T> toCopyOnWriteArrayList(T... elements) {
        return toCopyOnWriteArrayList((Force<T>) null, elements);
    }

    public static <T> CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Force<T> force, T... elements) {
        if(elements == null || elements.length == 0) return new CopyOnWriteArrayList<>();
        ArrayList<T> ts = toArrayList(force, elements);
        if(ts.isEmpty()) return new CopyOnWriteArrayList<>();
        return new CopyOnWriteArrayList<>(ts);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Comparator<? super T> c, T... elements) {
        return toCopyOnWriteArrayList(c, null, elements);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Comparator<? super T> c, Force<T> force, T... elements) {
        CopyOnWriteArrayList<T> result = toCopyOnWriteArrayList(force, elements);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Collection<? extends T> elements) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArrayList<>();
        return new CopyOnWriteArrayList<>(elements);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArrayList<>();
        if(force == null) return new CopyOnWriteArrayList<>(elements);
        ArrayList<T> ts = toArrayList(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArrayList<>();
        return new CopyOnWriteArrayList<>(ts);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Collection<? extends T> elements, Comparator<? super T> c) {
        return toCopyOnWriteArrayList(elements, (Force<T>) null, c);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Collection<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        CopyOnWriteArrayList<T> result = toCopyOnWriteArrayList(elements, force);
        if (result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(OwnRows<? extends T> elements) {
        return toCopyOnWriteArrayList(elements, (Force<T>) null);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArrayList<>();
        ArrayList<T> ts = toArrayList(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArrayList<>();
        return new CopyOnWriteArrayList<>(ts);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(OwnRows<? extends T> elements, Comparator<? super T> c) {
        return toCopyOnWriteArrayList(elements, (Force<T>) null, c);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(OwnRows<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        CopyOnWriteArrayList<T> result = toCopyOnWriteArrayList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Iterable<? extends T> elements) {
        return toCopyOnWriteArrayList(elements, (Force<T>) null);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new CopyOnWriteArrayList<>();
        ArrayList<T> ts = toArrayList(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArrayList<>();
        return new CopyOnWriteArrayList<>(ts);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Iterable<? extends T> elements, Comparator<? super T> c) {
        return toCopyOnWriteArrayList(elements, (Force<T>) null, c);
    }

    public static <T>CopyOnWriteArrayList<T> toCopyOnWriteArrayList(Iterable<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        CopyOnWriteArrayList<T> result = toCopyOnWriteArrayList(elements, force);
        if(result.isEmpty()) return result;
        result.sort(c);
        return result;
    }

    /* *******************************************************************************************
     *
     *           Set 集合
     *
     * *******************************************************************************************
     * */

    @SafeVarargs
    public static <T>HashSet<T> toHashSet(T... elements) {
        return toHashSet((Force<T>) null, elements);
    }

    public static <T>HashSet<T> toHashSet(Force<T> force, T... elements) {
        if(elements == null) return new HashSet<>();
        int length = elements.length;
        if(length == 0) return new HashSet<>();
        return (HashSet<T>) private_asCollection(new HashSet<>(MapEnum.calcInitSize(length)), elements, force);
    }

    public static <T>HashSet<T> toHashSet(Collection<? extends T> elements) {
        if(elements == null || elements.isEmpty()) return new HashSet<>();
        return new HashSet<>(elements);
    }

    public static <T>HashSet<T> toHashSet(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new HashSet<>();
        return (HashSet<T>) private_asCollection(new HashSet<>(default_calcSize(elements.size())), elements, force);
    }

    public static <T>HashSet<T> toHashSet(OwnRows<? extends T> elements) {
        return toHashSet(elements, (Force<T>) null);
    }

    public static <T>HashSet<T> toHashSet(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new HashSet<>();
        return (HashSet<T>) private_asCollection(new HashSet<>(default_calcSize(elements.size())), elements, force);
    }

    public static <T>HashSet<T> toHashSet(Iterable<? extends T> elements) {
        return toHashSet(elements, (Force<T>) null);
    }

    public static <T>HashSet<T> toHashSet(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new HashSet<>();
        int size = default_getIterableLength(elements);
        if(size == 0) return new HashSet<>();
        return (HashSet<T>) private_asCollection(new HashSet<>(default_calcSize(size)), elements, force);
    }

    @SafeVarargs
    public static <T>LinkedHashSet<T> toLinkedHashSet(T... elements) {
        return toLinkedHashSet((Force<T>) null, elements);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(Force<T> force, T... elements) {
        if(elements == null) return new LinkedHashSet<>();
        int length = elements.length;
        if(length == 0) return new LinkedHashSet<>();
        return (LinkedHashSet<T>) private_asCollection(new LinkedHashSet<>(default_calcSize(length)), elements, force);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(Collection<? extends T> elements) {
        if(elements == null || elements.isEmpty()) return new LinkedHashSet<>();
        return new LinkedHashSet<>(elements);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new LinkedHashSet<>();
        return (LinkedHashSet<T>) private_asCollection(new LinkedHashSet<>(default_calcSize(elements.size())), elements, force);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(OwnRows<? extends T> elements) {
        return toLinkedHashSet(elements, (Force<T>) null);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new LinkedHashSet<>();
        return (LinkedHashSet<T>) private_asCollection(new LinkedHashSet<>(default_calcSize(elements.size())), elements, force);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(Iterable<? extends T> elements) {
        return toLinkedHashSet(elements, (Force<T>) null);
    }

    public static <T>LinkedHashSet<T> toLinkedHashSet(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new LinkedHashSet<>();
        int size = default_getIterableLength(elements);
        if(size == 0) return new LinkedHashSet<>();
        return (LinkedHashSet<T>) private_asCollection(new LinkedHashSet<>(default_calcSize(size)), elements, force);
    }

    @SafeVarargs
    public static <T> ConcurrentHashSet<T> toConcurrentHashSet(T... elements) {
        return new ConcurrentHashSet<>(elements);
    }

    public static <T> ConcurrentHashSet<T> toConcurrentHashSet(Force<T> force, T... elements) {
        if(elements == null) return new ConcurrentHashSet<>();
        int length = elements.length;
        if(length == 0) return new ConcurrentHashSet<>();
        return (ConcurrentHashSet<T>) private_asCollection(new ConcurrentHashSet<>(length), elements, force);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(Collection<? extends T> elements) {
        return new ConcurrentHashSet<>(elements);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new ConcurrentHashSet<>();
        return (ConcurrentHashSet<T>) private_asCollection(new ConcurrentHashSet<>(elements.size()), elements, force);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(OwnRows<? extends T> elements) {
        return new ConcurrentHashSet<>(elements);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new ConcurrentHashSet<>();
        return (ConcurrentHashSet<T>) private_asCollection(new ConcurrentHashSet<>(elements.size()), elements, force);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(Iterable<? extends T> elements) {
        return new ConcurrentHashSet<>(elements);
    }

    public static <T>ConcurrentHashSet<T> toConcurrentHashSet(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new ConcurrentHashSet<>();
        int size = default_getIterableLength(elements);
        if(size == 0) return new ConcurrentHashSet<>();
        return (ConcurrentHashSet<T>) private_asCollection(new ConcurrentHashSet<>(size), elements, force);
    }

    @SafeVarargs
    public static <T> CopyOnWriteArraySet<T> toCopyOnWriteArraySet(T... elements) {
        return toCopyOnWriteArraySet((Force<T>) null, elements);
    }

    public static <T> CopyOnWriteArraySet<T> toCopyOnWriteArraySet(Force<T> force, T... elements) {
        if(elements == null || elements.length == 0) return new CopyOnWriteArraySet<>();
        HashSet<T> ts = toHashSet(force, elements);
        if(ts.isEmpty()) return new CopyOnWriteArraySet<>();
        return new CopyOnWriteArraySet<>(ts);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(Collection<? extends T> elements) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArraySet<>();
        return new CopyOnWriteArraySet<>(elements);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(Collection<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArraySet<>();
        if(force == null) return new CopyOnWriteArraySet<>(elements);
        HashSet<T> ts = toHashSet(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArraySet<>();
        return new CopyOnWriteArraySet<>(ts);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(OwnRows<? extends T> elements) {
        return toCopyOnWriteArraySet(elements, (Force<T>) null);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(OwnRows<? extends T> elements, Force<T> force) {
        if(elements == null || elements.isEmpty()) return new CopyOnWriteArraySet<>();
        HashSet<T> ts = toHashSet(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArraySet<>();
        return new CopyOnWriteArraySet<>(ts);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(Iterable<? extends T> elements) {
        return toCopyOnWriteArraySet(elements, (Force<T>) null);
    }

    public static <T>CopyOnWriteArraySet<T> toCopyOnWriteArraySet(Iterable<? extends T> elements, Force<T> force) {
        if(elements == null) return new CopyOnWriteArraySet<>();
        HashSet<T> ts = toHashSet(elements, force);
        if(ts.isEmpty()) return new CopyOnWriteArraySet<>();
        return new CopyOnWriteArraySet<>(ts);
    }

    @SafeVarargs
    public static <T> TreeSet<T> toTreeSet(T... elements) {
        return toTreeSet((Comparator<T>) null, null, elements);
    }

    public static <T> TreeSet<T> toTreeSet(Force<T> force, T... elements) {
        return toTreeSet((Comparator<T>) null, force, elements);
    }

    public static <T> TreeSet<T> toTreeSet(Comparator<? super T> c, T... elements) {
        return toTreeSet(c, null, elements);
    }

    public static <T> TreeSet<T> toTreeSet(Comparator<? super T> c, Force<T> force, T... elements) {
        if(elements == null || elements.length == 0) return new TreeSet<>(c);
        return (TreeSet<T>) private_asCollection(new TreeSet<>(c), elements, force);
    }

    public static <T>TreeSet<T> toTreeSet(Collection<? extends T> elements) {
        if(elements == null || elements.isEmpty()) return new TreeSet<>();
        return new TreeSet<>(elements);
    }

    public static <T>TreeSet<T> toTreeSet(Collection<? extends T> elements, Force<T> force) {
        return toTreeSet(elements, force, null);
    }

    public static <T>TreeSet<T> toTreeSet(Collection<? extends T> elements, Comparator<? super T> c) {
        if(elements == null || elements.isEmpty()) return new TreeSet<>(c);
        TreeSet<T> result = new TreeSet<>(c);
        result.addAll(elements);
        return result;
    }

    public static <T>TreeSet<T> toTreeSet(Collection<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null || elements.isEmpty()) return new TreeSet<>(c);
        return (TreeSet<T>) private_asCollection(new TreeSet<>(c), elements, force);
    }


    public static <T>TreeSet<T> toTreeSet(OwnRows<? extends T> elements) {
        return toTreeSet(elements, (Force<T>) null, null);
    }

    public static <T>TreeSet<T> toTreeSet(OwnRows<? extends T> elements, Force<T> force) {
        return toTreeSet(elements, force, null);
    }

    public static <T>TreeSet<T> toTreeSet(OwnRows<? extends T> elements, Comparator<? super T> c) {
        return toTreeSet(elements, (Force<T>) null, c);
    }

    public static <T>TreeSet<T> toTreeSet(OwnRows<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null || elements.isEmpty()) return new TreeSet<>(c);
        return (TreeSet<T>) private_asCollection(new TreeSet<>(c), elements, force);
    }

    public static <T>TreeSet<T> toTreeSet(Iterable<? extends T> elements) {
        return toTreeSet(elements, (Force<T>) null, null);
    }

    public static <T>TreeSet<T> toTreeSet(Iterable<? extends T> elements, Force<T> force) {
        return toTreeSet(elements, force, null);
    }

    public static <T>TreeSet<T> toTreeSet(Iterable<? extends T> elements, Comparator<? super T> c) {
        return toTreeSet(elements, (Force<T>) null, c);
    }

    public static  <T>TreeSet<T> toTreeSet(Iterable<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null) return new TreeSet<>(c);
        return (TreeSet<T>) private_asCollection(new TreeSet<>(c), elements, force);
    }

    @SafeVarargs
    public static <T> ConcurrentSkipListSet<T> toConcurrentSkipListSet(T... elements) {
        return toConcurrentSkipListSet((Comparator<? super T>) null, null, elements);
    }

    public static <T> ConcurrentSkipListSet<T> toConcurrentSkipListSet(Force<T> force, T... elements) {
        return toConcurrentSkipListSet((Comparator<? super T>) null, force, elements);
    }

    public static <T> ConcurrentSkipListSet<T> toConcurrentSkipListSet(Comparator<? super T> c, T... elements) {
        return toConcurrentSkipListSet(c, null, elements);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Comparator<? super T> c, Force<T> force, T... elements) {
        if(elements == null || elements.length == 0) return new ConcurrentSkipListSet<>(c);
        return (ConcurrentSkipListSet<T>) private_asCollection(new ConcurrentSkipListSet<>(c), elements, force);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Collection<? extends T> elements) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Collection<? extends T> elements, Force<T> force) {
        return toConcurrentSkipListSet(elements, force, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Collection<? extends T> elements, Comparator<? super T> c) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, c);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Collection<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null || elements.isEmpty()) return new ConcurrentSkipListSet<>(c);
        return (ConcurrentSkipListSet<T>) private_asCollection(new ConcurrentSkipListSet<>(c), elements, force);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(OwnRows<? extends T> elements) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(OwnRows<? extends T> elements, Force<T> force) {
        return toConcurrentSkipListSet(elements, force, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(OwnRows<? extends T> elements, Comparator<? super T> c) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, c);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(OwnRows<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null || elements.isEmpty()) return new ConcurrentSkipListSet<>(c);
        return (ConcurrentSkipListSet<T>) private_asCollection(new ConcurrentSkipListSet<>(c), elements, force);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Iterable<? extends T> elements) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Iterable<? extends T> elements, Force<T> force) {
        return toConcurrentSkipListSet(elements, force, null);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Iterable<? extends T> elements, Comparator<? super T> c) {
        return toConcurrentSkipListSet(elements, (Force<T>) null, c);
    }

    public static <T>ConcurrentSkipListSet<T> toConcurrentSkipListSet(Iterable<? extends T> elements, Force<T> force, Comparator<? super T> c) {
        if(elements == null) return new ConcurrentSkipListSet<>(c);
        return (ConcurrentSkipListSet<T>) private_asCollection(new ConcurrentSkipListSet<>(c), elements, force);
    }

    /* *******************************************************************************************
     *
     *           数组
     *
     * *******************************************************************************************
     * */

    public static <T>T[] toArray(Class<T> componentType, T... elements) {
        return toArray(componentType, null, elements);
    }

    public static <T>T[] toArray(Class<T> componentType, Force<T> force, T... elements) {
        if(componentType == null) throw new NullPointerException("目标数组的类型为 null");
        if(elements == null) return (T[]) Array.newInstance(componentType, 0);
        int length = elements.length;
        if(length == 0) return (T[]) Array.newInstance(componentType, 0);
        Object result = Array.newInstance(componentType, length);
        if(force == null) System.arraycopy(elements, 0, result, 0, length);
        else for (int i = 0; i < length; i++) Array.set(result, i, force.force(elements[i]));
        return (T[]) result;
    }

    public static <T>T[] toArray(Collection<? extends T> elements, Class<T> componentType) {
        return toArray(elements, componentType, null);
    }

    public static <T>T[] toArray(Collection<? extends T> elements, Class<T> componentType, Force<T> force) {
        if(componentType == null) throw new NullPointerException("目标数组的类型为 null");
        if(elements == null) return (T[]) Array.newInstance(componentType, 0);
        return (T[]) private_asArray(elements.size(), elements, componentType, force);
    }

    public static <T>T[] toArray(OwnRows<? extends T> elements, Class<T> componentType) {
        return toArray(elements, componentType, null);
    }

    public static <T>T[] toArray(OwnRows<? extends T> elements, Class<T> componentType, Force<T> force) {
        if(componentType == null) throw new NullPointerException("目标数组的类型为 null");
        if(elements == null) return (T[]) Array.newInstance(componentType, 0);
        return (T[]) private_asArray(elements.size(), elements, componentType, force);
    }

    public static <T>T[] toArray(Iterable<? extends T> elements, Class<T> componentType) {
        return toArray(elements, componentType, null);
    }

    public static <T>T[] toArray(Iterable<? extends T> elements, Class<T> componentType, Force<T> force) {
        if(componentType == null) throw new NullPointerException("目标数组的类型为 null");
        if(elements == null) return (T[]) Array.newInstance(componentType, 0);
        return (T[]) private_asArray(default_getIterableLength(elements), elements, componentType, force);
    }

    /* ************************************************************************************************************
     *
     *          拷贝
     *
     * ************************************************************************************************************
     * */

    public static <T>void copy(T[] src, T[] tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(T[] src, T[] tar, Force<T> force) {
        if(src == null || src.length == 0 || tar == null || tar.length == 0) return;
        int length = Math.min(src.length, tar.length);
        if(force == null) System.arraycopy(src, 0, tar, 0, length);
        else for (int i = 0; i < length; i++) tar[i] = force.force(src[i]);
    }

    public static <T>void copy(T[] src, Collection<T> tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(T[] src, Collection<T> tar, Force<T> force) {
        if(src == null || src.length == 0 || tar == null) return;
        if(force == null) Collections.addAll(tar, src);
        else for (T t : src) tar.add(force.force(t));
    }

    public static <T>void copy(T[] src, OwnRows<T> tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(T[] src, OwnRows<T> tar, Force<T> force) {
        if(src == null || src.length == 0 || tar == null) return;
        if(force == null) tar.addAll(src);
        else for (T t : src) tar.add(force.force(t));
    }

    public static <T>void copy(Iterable<? extends T> src, Collection<T> tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(Iterable<? extends T> src, Collection<T> tar, Force<T> force) {
        if(src == null || tar == null) return;
        if(force == null) for (T t : src) tar.add(t);
        else for (T t : src) tar.add(force.force(t));
    }

    public static <T>void copy(Iterable<? extends T> src, OwnRows<T> tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(Iterable<? extends T> src, OwnRows<T> tar, Force<T> force) {
        if(src == null || tar == null) return;
        if(force == null) tar.addAll(src);
        else for (T t : src) tar.add(force.force(t));
    }

    public static <T>void copy(Iterable<? extends T> src, T[] tar) {
        copy(src, tar, null);
    }

    public static <T>void copy(Iterable<? extends T> src, T[] tar, Force<T> force) {
        if(src == null || tar == null || tar.length == 0) return;
        int index = 0;
        int length = tar.length;
        if(force == null) {
            for (T t : src) {
                if(index == length) return;
                tar[index] = t;
                index++;
            }
            return;
        }
        for (T t : src) {
            if(index == length) return;
            tar[index] = force.force(t);
            index++;
        }
    }

    /* *******************************************************************************************
     *
     *           私有逻辑
     *
     * *******************************************************************************************
     * */

    @Note("将可迭代容器的数据拷贝到新数组里返回")
    private static Object private_asArray(int length, Iterable data, Class<?> mainType, Force force) {
        if(length == 0) return Array.newInstance(mainType, 0);
        Object result = Array.newInstance(mainType, length);
        int index = 0;
        if(force == null) {
            for (Object o : data) {
                if(index == length) return result;
                Array.set(result, index, o);
                index++;
            }
            return result;
        }
        for (Object o : data) {
            if(index == length) return result;
            Array.set(result, index, force.force(o));
            index++;
        }
        return result;
    }

    private static <T>Collection<T> private_asCollection(Collection<T> result, T[] elements, Force<T> force) {
        if(force == null) Collections.addAll(result, elements);
        else for (T t : elements) result.add(force.force(t));
        return result;
    }


    private static <T>Collection<T> private_asCollection(Collection<T> result, Iterable<? extends T> elements, Force<T> force) {
        if(force == null) for (T t : elements) result.add(t);
        else for (T t : elements) result.add(force.force(t));
        return result;
    }
}
